﻿using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using AnjLab.SyncIT.Core.Api;
using Microsoft.Office.Interop.Outlook;

namespace AnjLab.SyncIT.Core.Data.Outlook
{
    public abstract class OutlookFolder
    {
        readonly MAPIFolder outlookFolder;
        private const string FindIdRegexPattern = @"{0} \#(?<id>[0-9,a-f]+)";

        protected OutlookFolder(OlDefaultFolders folder)
        {
            var application = new ApplicationClass();
            outlookFolder = application.Session.GetDefaultFolder(folder);
        }

        public MAPIFolder ParentFolder
        {
            get{ return outlookFolder; }
        }

        public abstract OutlookDestination OutlookDestination { get; }

        public static string GetOutlookItemId(string prefix, string itemID)
        {
            return string.Format("{0} #{1}", prefix.Replace("'", "''"), itemID);
        }
        
        public IOutlookItem FindItem(string prefix, string itemID)
        {
            var key = GetOutlookItemId(prefix, itemID);
            foreach(var sItem in outlookFolder.Items)
            {
                var item = GetItem(sItem, itemID);

                if (string.IsNullOrEmpty(item.Body))
                {
                    continue;
                }

                if (item.Body.Contains(key))
                    return item;
            }
            return GetItem(null, itemID);
        }

        protected abstract IOutlookItem GetItem(object comSourceObject, string itemId);

        private static Regex FormatFindItemIdExpression(string prefix)
        {
            return new Regex(string.Format(FindIdRegexPattern, prefix.Replace("'", "''")),
                                 RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
        }

        public IList<IOutlookItem> FindModifiedItems(DateTime modifiedSince, string prefix)
        {
            var result = new List<IOutlookItem>();
            var filter = string.Format("[LastModificationTime] >= '{0}'", modifiedSince.ToShortDateString());

            var findIdExpr = FormatFindItemIdExpression(prefix);
            foreach (var item in outlookFolder.Items.Restrict(filter))
            {
                var i = GetItem(item, string.Empty);

                if (string.IsNullOrEmpty(i.Body))
                {
                    continue;
                }

                var match = findIdExpr.Match(i.Body);
                if (match.Success)
                {
                    i.ItemID = match.Groups["id"].Value;
                    result.Add(i);
                }
            }
            return result;
        }

        public IList<IOutlookItem> FindOpenedItems(string prefix)
        {
            var result = new List<IOutlookItem>();
            var findIdExpr = FormatFindItemIdExpression(prefix);
            foreach (var item in outlookFolder.Items)
            {
                var i = GetItem(item, string.Empty);
                if (!i.Complete)
                {
                    if (string.IsNullOrEmpty(i.Body))
                    {
                        continue;
                    }

                    var match = findIdExpr.Match(i.Body);
                    if (match.Success)
                    {
                        i.ItemID = match.Groups["id"].Value;
                        result.Add(i);
                    }
                }
            }
            return result;
        }

        public abstract IOutlookItem CreateNewItem();
    }
}